#ifndef _BPCANALY_CPP
#define _BPCANALY_CPP
#include<Arduino.h>

typedef struct TIMESTAMP
{
  byte YEAR;
  byte MONTH;
  byte DAY;
  
  byte WEEK;
  byte MINUTE;
  byte HOUR;
  byte SECOND;
  
  bool VERIFY1;//第一部分的奇偶校验，1为异常，0为正常
  bool VERIFY2;//第二部分的奇偶校验，1为异常。0为正常
  };

void init_pin(int Modpin,int enable)
{
  pinMode(Modpin,INPUT);
  pinMode(enable,OUTPUT);
  digitalWrite(enable,LOW);
}

signed long int WaitForInitSign(int Modpin)//低电平脉冲的时间
{
  signed long int fstPULSE;//第一个脉冲出现的时间
  signed long int lstPULSE;//第二个脉冲出现的时间
  while(digitalRead(Modpin)==LOW);//当读取到的电平是低电平一直等待
  
  if(digitalRead(Modpin)==HIGH)
  fstPULSE=millis();
  //Serial.print(fstPULSE);
  while(digitalRead(Modpin)==HIGH);//高电平的出现时间已经记录下来，所以等待下一个高电平的出现
  while(digitalRead(Modpin)==LOW);

  if(digitalRead(Modpin)==HIGH)
  lstPULSE=millis();
  //Serial.print(lstPULSE);
  
  return (lstPULSE-fstPULSE);
}

signed long int HighPulseTime(int Modpin)//高电平脉冲的时间
{
  signed long int fstPULSE;
  signed long int lstPULSE;
  while(digitalRead(Modpin)==LOW);//等待高电平的出现
  
  if(digitalRead(Modpin)==HIGH)//电平跳变到高电平时记录出现时间
    fstPULSE=millis();
    
  while(digitalRead(Modpin)==HIGH);//等待低电平的出现
  
  if(digitalRead(Modpin)==LOW)
    lstPULSE=millis();

  return (lstPULSE-fstPULSE);
}

byte ConvPulseToData(signed long int param)//脉冲时长转换为BPC4进制信息码
{
    byte res;
    if(param>=50 && param<=150)
    return 0;
    if(param>150 && param<=250)
    return 1;
    if(param>250 && param<=350)
    return 2;
    if(param>350 && param<=450)
    return 3;

    return 8;//异常数值
}

void ANALY(char* SaveTo,int Modpin)//分析并保存元数据
{
  while(1)
  {
    if(WaitForInitSign(Modpin)>1500)//等待时间信号起始帧开始
    break;
    else
    continue;
  }
  for(int i=0;i<19;i++)
  SaveTo[i]=ConvPulseToData(HighPulseTime(Modpin));
}

int NumberOfOne(byte data)//奇偶校验计算1的数量
{
    int numb = 0;
    for (int i = 0; i < 8; i++)
    {
        if ((data & 0x80) == 0x80)
        {
            numb++;
            data <<= 1;
        }
        else
            data <<= 1;
    }
    return numb;
}

TIMESTAMP TransferToStandardForm(char* SaveTo)//将时间格式转换为标准格式
{
  TIMESTAMP RES;
  int NUMB1,NUMB2;
  RES.YEAR=SaveTo[15]*16+SaveTo[16]*4+SaveTo[17];
    if(SaveTo[18]==2 || SaveTo[18]==3)
    RES.YEAR+=100;//第19位校验位同时表示奇偶校验结果和21世纪还是22世纪

  RES.MONTH=SaveTo[13]*4+SaveTo[14];
  RES.DAY=SaveTo[10]*16+SaveTo[11]*4+SaveTo[12];
  RES.WEEK=SaveTo[7]*4+SaveTo[8];

  RES.MINUTE=SaveTo[4]*16+SaveTo[5]*4+SaveTo[6];
  RES.HOUR=SaveTo[2]*4+SaveTo[3];
    if(SaveTo[9]==2 || SaveTo[9]==3)//如果校验位为2或者3代表为下午
    RES.HOUR+=12;
  RES.SECOND=SaveTo[0]*20;

  NUMB1=0;
  NUMB2=0;
  for(int i=0;i<9;i++)
  NUMB1+=NumberOfOne(SaveTo[i]);//奇偶校验：计算1～9段数据中1的数量
  for(int i=10;i<18;i++)
  NUMB2+=NumberOfOne(SaveTo[i]);//奇偶校验：计算11～18段数据中1的数量
  Serial.println(NUMB1);
  Serial.println(NUMB2);
  if(SaveTo[9]==0 || SaveTo[9]==2)//如果奇偶校验是偶数，则验证1的数量是否能被1整除
  {
    if((NUMB1%2)==0)
    RES.VERIFY1=0;
    else
    RES.VERIFY1=1;
  }
  if(SaveTo[9]==1 || SaveTo[9]==3)
  {
    if((NUMB1%2)==1)
    RES.VERIFY1=0;
    else
    RES.VERIFY1=1;  
  }

  if(SaveTo[18]==0 || SaveTo[18]==2)
  {
    if((NUMB2%2)==0)
    RES.VERIFY2=0;
    else
    RES.VERIFY2=1;
  }
  if(SaveTo[18]==1 || SaveTo[18]==3)
  {
    if((NUMB2%2)==1)
    RES.VERIFY2=0;
    else
    RES.VERIFY2=1;  
  }
  
  return RES;
}

#endif
